%%%-------------------------------------------------------------------
%%% @author wukai
%%% @copyright (C) 2017, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 20. 十二月 2017 17:46
%%%-------------------------------------------------------------------
-module(subscribe_server).
-author("wukai").
-behaviour(gen_server).
-define(SUBSCRIBE_TABLE, subscriber).

-record(subscriber,{
  client,%%客户端id
  filter,%%主题过滤器
  reg,%%替换为正则表达式
  pid,
  qos%%消息质量
}).
-export([start_link/0]).
-export([cre_tab/0]).
-export([send_delete/1]).
-export([send_sub/3]).
-export([send_unsub/3]).
-export([init/1,
  handle_call/3,
  handle_cast/2,
  handle_info/2,
  terminate/2,
  code_change/3]).

-define(SERVER, ?MODULE).

-record(state, {}).
start_link() ->
  gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

init([]) ->
  {ok, #state{}}.
handle_call(_Request, _From, State) ->
  {reply, ok, State}.

handle_cast({unsub,TopicList,Client,Pid}, State) ->
  unsub_topics(TopicList,Client,Pid),
  {noreply, State};

handle_cast({sub,TopicList,Client,Pid}, State) ->
  %%log:log("sub info ~p,~p,~p",[TopicList,Client,Pid]),
  sub_topics(TopicList,Client,Pid),
  {noreply, State};

handle_cast({delete,Client}, State) ->
  delete(Client),
  {noreply, State};
handle_cast(_Request, State) ->
  {noreply, State}.

handle_info(_Info, State) ->
  {noreply, State}.
terminate(_Reason, _State) ->
  ok.
code_change(_OldVsn, State, _Extra) ->
  {ok, State}.

cre_tab() ->
%%创建订阅ETS表
  ets:new(?SUBSCRIBE_TABLE, [
    bag, public, named_table,
    %%此处参数为并发读写
    {write_concurrency, true}, {read_concurrency, true},
    %%设置主键
    {keypos, #subscriber.filter}]).
sub_topics(TopicList,Client,Pid) ->

  List = [#subscriber{client = Client,pid=Pid,qos = Qos,reg=null,filter = Filter}||{Filter,Qos}<-TopicList],
 %%正则替换模式
%%List = [#subscriber{client = Client,pid=Pid,qos = Qos,filter = Filter,reg =okmqtt_topic:fix(Filter)}||{Filter,Qos}<-TopicList],
  lists:foreach(fun(E) ->
    ets:insert(?SUBSCRIBE_TABLE, E) end, List).

%%取消订阅
unsub_topics(TopicList,Client,Pid) ->
  List = [#subscriber{client = Client,pid=Pid,qos = '_',filter = Filter,reg = '_'}||Filter<-TopicList],
  lists:foreach(fun(E) ->
    ets:match_delete(?SUBSCRIBE_TABLE, E) end, List).
%%删除某客户端所有订阅
delete(Client)->
  ets:match_delete(?SUBSCRIBE_TABLE,#subscriber{client=Client,_='_',_='_',_='_'}).

send_unsub(TopicList,Client,Pid)->gen_server:cast(?MODULE,{{unsub,TopicList,Client,Pid}}).
send_delete(Client)->gen_server:cast(?MODULE,{{delete,Client}}).
send_sub(TopicList,Client,Pid)-> gen_server:cast(?MODULE,{sub,TopicList,Client,Pid}).
